<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>webdoc</title>
    <link rel="stylesheet" type="text/css" href="../static/css/main.css">
</head>
<body>
<div class="nav">
    <div class="logo">
        
            webdoc
        
    </div>
<ul><li><a href="../index.html">0.Async</a></li><li><a href="../html/0.editor.html">0.editor</a></li><li><a href="../html/0.module.html">0.module</a></li><li><a href="../html/1.ES2015.html">1.ES2015</a></li><li><a href="../html/2.Promise.html">2.Promise</a></li><li><a href="../html/3.Node.html">3.Node</a></li><li><a href="../html/4.NodeInstall.html">4.NodeInstall</a></li><li><a href="../html/5.REPL.html">5.REPL</a></li><li><a href="../html/6.NodeCore.html">6.NodeCore</a></li><li><a href="../html/7.module&NPM.html">7.module&NPM</a></li><li><a href="../html/8.Encoding.html">8.Encoding</a></li><li><a href="../html/9.Buffer.html">9.Buffer</a></li><li><a href="../html/10.fs.html">10.fs</a></li><li><a href="../html/11.Stream-1.html">11.Stream-1</a></li><li><a href="../html/11.Stream-2.html">11.Stream-2</a></li><li><a href="../html/11.Stream-3.html">11.Stream-3</a></li><li><a href="../html/11.Stream-4.html">11.Stream-4</a></li><li><a href="../html/12-Network-2.html">12-Network-2</a></li><li><a href="../html/12.NetWork-3.html">12.NetWork-3</a></li><li><a href="../html/12.Network-1.html">12.Network-1</a></li><li><a href="../html/13.tcp.html">13.tcp</a></li><li><a href="../html/14.http-1.html">14.http-1</a></li><li><a href="../html/14.http-2.html">14.http-2</a></li><li><a href="../html/15.compress.html">15.compress</a></li><li><a href="../html/16.crypto.html">16.crypto</a></li><li><a href="../html/17.process.html">17.process</a></li><li><a href="../html/18.yargs.html">18.yargs</a></li><li><a href="../html/19.cache.html">19.cache</a></li><li><a href="../html/20.action.html">20.action</a></li><li><a href="../html/21.https.html">21.https</a></li><li><a href="../html/22.cookie.html">22.cookie</a></li><li><a href="../html/23.session.html">23.session</a></li><li><a href="../html/24.express-1.html">24.express-1</a></li><li><a href="../html/24.express-2.html">24.express-2</a></li><li><a href="../html/24.express-3.html">24.express-3</a></li><li><a href="../html/24.express-4.html">24.express-4</a></li><li><a href="../html/25.koa-1.html">25.koa-1</a></li><li><a href="../html/26.webpack-1-basic.html">26.webpack-1-basic</a></li><li><a href="../html/26.webpack-2-optimize.html">26.webpack-2-optimize</a></li><li><a href="../html/26.webpack-3.tapable.html">26.webpack-3.tapable</a></li><li><a href="../html/26.webpack-4-AST.html">26.webpack-4-AST</a></li><li><a href="../html/26.webpack-5-source.html">26.webpack-5-source</a></li><li><a href="../html/26.webpack-6-loader.html">26.webpack-6-loader</a></li><li><a href="../html/26.webpack-7-plugin.html">26.webpack-7-plugin</a></li><li><a href="../html/26.webpack-8-hand.html">26.webpack-8-hand</a></li><li><a href="../html/27.react-1.html">27.react-1</a></li><li><a href="../html/27.react-2.html">27.react-2</a></li><li><a href="../html/27.react-3.html">27.react-3</a></li><li><a href="../html/27.react-4-immutable.html">27.react-4-immutable</a></li><li><a href="../html/27.react-5-react-dom-diff.html">27.react-5-react-dom-diff</a></li><li><a href="../html/27.react-6.html">27.react-6</a></li><li class="active"><a href="../html/28.react-mobx.html">28.react-mobx</a></li><li><a href="../html/28.redux-0.html">28.redux-0</a></li><li><a href="../html/28.redux-1.html">28.redux-1</a></li><li><a href="../html/28.redux-2-中间件.html">28.redux-2-中间件</a></li><li><a href="../html/28.redux-3-saga.html">28.redux-3-saga</a></li><li><a href="../html/28.redux-jwt-back.html">28.redux-jwt-back</a></li><li><a href="../html/28.redux-jwt-front.html">28.redux-jwt-front</a></li><li><a href="../html/29.mongodb-1.html">29.mongodb-1</a></li><li><a href="../html/29.mongodb-2.html">29.mongodb-2</a></li><li><a href="../html/29.mongodb-3.html">29.mongodb-3</a></li><li><a href="../html/29.mongodb-4.html">29.mongodb-4</a></li><li><a href="../html/29.mongodb-5.html">29.mongodb-5</a></li><li><a href="../html/29.mongodb-6.html">29.mongodb-6</a></li><li><a href="../html/30.cms-1-mysql.html">30.cms-1-mysql</a></li><li><a href="../html/30.cms-2-mysql.html">30.cms-2-mysql</a></li><li><a href="../html/30.cms-3-mysql.html">30.cms-3-mysql</a></li><li><a href="../html/30.cms-4-egg.html">30.cms-4-egg</a></li><li><a href="../html/30.cms-5-api.html">30.cms-5-api</a></li><li><a href="../html/30.cms-6-roadhog.html">30.cms-6-roadhog</a></li><li><a href="../html/30.cms-7-umi.html">30.cms-7-umi</a></li><li><a href="../html/30.cms-8-dva.html">30.cms-8-dva</a></li><li><a href="../html/30.cms-9-dva.html">30.cms-9-dva</a></li><li><a href="../html/30.cms-10-dva.html">30.cms-10-dva</a></li><li><a href="../html/30.cms-11-front.html">30.cms-11-front</a></li><li><a href="../html/31.cms-12-api.html">31.cms-12-api</a></li><li><a href="../html/31.cms-13-front.html">31.cms-13-front</a></li><li><a href="../html/31.cms-14-deploy.html">31.cms-14-deploy</a></li><li><a href="../html/32.ant.html">32.ant</a></li><li><a href="../html/33.redis.html">33.redis</a></li><li><a href="../html/34.unittest.html">34.unittest</a></li><li><a href="../html/35.jwt.html">35.jwt</a></li><li><a href="../html/36.websocket-1.html">36.websocket-1</a></li><li><a href="../html/36.websocket-2.html">36.websocket-2</a></li><li><a href="../html/38.chat-api-1.html">38.chat-api-1</a></li><li><a href="../html/38.chat-api-2.html">38.chat-api-2</a></li><li><a href="../html/38.chat-3.html">38.chat-3</a></li><li><a href="../html/38.chat-api-3.html">38.chat-api-3</a></li><li><a href="../html/38.chat.html">38.chat</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/39.crawl-0.html">39.crawl-0</a></li><li><a href="../html/39.crawl-1.html">39.crawl-1</a></li><li><a href="../html/39.crawl-2.html">39.crawl-2</a></li><li><a href="../html/40.deploy.html">40.deploy</a></li><li><a href="../html/41.safe.html">41.safe</a></li><li><a href="../html/42.test.html">42.test</a></li><li><a href="../html/43.nginx.html">43.nginx</a></li><li><a href="../html/44.enzyme.html">44.enzyme</a></li><li><a href="../html/45.docker.html">45.docker</a></li><li><a href="../html/46.elastic.html">46.elastic</a></li><li><a href="../html/47.oauth.html">47.oauth</a></li><li><a href="../html/48.wxpay.html">48.wxpay</a></li><li><a href="../html/49.nunjucks.html">49.nunjucks</a></li><li><a href="../html/50.ketang.html">50.ketang</a></li><li><a href="../html/index.html">index</a></li><li><a href="../html/51.typescript.html">51.typescript</a></li><li><a href="../html/52.UML.html">52.UML</a></li><li><a href="../html/53.design.html">53.design</a></li><li><a href="../html/index.html">index</a></li></ul></div>


<div class="warpper">

    <div class="page-toc">
        <ul><li><a href="#t01. mobx">1. mobx</a></li><li><a href="#t12. mobx vs redux">2. mobx vs redux</a></li><li><a href="#t23. 核心思想">3. 核心思想</a></li><li><a href="#t34. 环境准备">4. 环境准备</a><ul><li><a href="#t44.1 安装依赖模块">4.1 安装依赖模块</a></li><li><a href="#t54.2 webpack.config.js">4.2 webpack.config.js</a></li><li><a href="#t64.3 package.json">4.3 package.json</a></li></ul></li><li><a href="#t75. Decorator">5. Decorator</a><ul><li><a href="#t85.1 类的修饰">5.1 类的修饰</a></li><li><a href="#t95.2 修饰属性">5.2 修饰属性</a></li><li><a href="#t105.3 修饰方法">5.3 修饰方法</a></li></ul></li><li><a href="#t116. Proxy">6. Proxy</a></li><li><a href="#t127. mobx">7. mobx</a><ul><li><a href="#t137.1 observable">7.1 observable</a><ul><li><a href="#t147.1.1 引用类型 (observable)">7.1.1 引用类型 (observable)</a></li><li><a href="#t157.1.2 基本类型(observable.box)">7.1.2 基本类型(observable.box)</a></li><li><a href="#t167.1.3 decorator">7.1.3 decorator</a></li></ul></li></ul></li><li><a href="#t178. 使用对可观察对象做出响应">8. 使用对可观察对象做出响应</a><ul><li><a href="#t188.1 computed">8.1 computed</a></li><li><a href="#t198.2 autorun">8.2 autorun</a></li><li><a href="#t208.3 when">8.3 when</a></li><li><a href="#t218.4 reaction">8.4 reaction</a></li></ul></li><li><a href="#t229. action">9. action</a><ul><li><a href="#t239.1 action">9.1 action</a></li><li><a href="#t249.2 action.bound">9.2 action.bound</a></li><li><a href="#t259.3 runInAction">9.3 runInAction</a></li></ul></li><li><a href="#t2610. mobx应用">10. mobx应用</a><ul><li><a href="#t2710.1 计数器">10.1 计数器</a></li><li><a href="#t2810.2 TODO">10.2 TODO</a></li></ul></li><li><a href="#t2911.优化">11.优化</a><ul><li><a href="#t3011.1 observe">11.1 observe</a></li><li><a href="#t3111.2 spy">11.2 spy</a></li><li><a href="#t3211.3 toJS">11.3 toJS</a></li><li><a href="#t3311.4 trace">11.4 trace</a></li><li><a href="#t3412. 优化">12. 优化</a></li></ul></li></ul>
    </div>
    
    <div class="content markdown-body">
        <h2 id="t01. mobx">1. mobx <a href="#t01. mobx"> # </a></h2>
<p>mobx&#x662F;&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x53EF;&#x6269;&#x5C55;&#x7684;&#x72B6;&#x6001;&#x7BA1;&#x7406;&#x5E93;</p>
<h2 id="t12. mobx vs redux">2. mobx vs redux <a href="#t12. mobx vs redux"> # </a></h2>
<p>mobx&#x5B66;&#x4E60;&#x6210;&#x672C;&#x66F4;&#x4F4E;&#xFF0C;&#x6027;&#x80FD;&#x66F4;&#x597D;&#x7684;&#x7684;&#x72B6;&#x6001;&#x89E3;&#x51B3;&#x65B9;&#x6848;</p>
<ul>
<li>&#x5F00;&#x53D1;&#x96BE;&#x5EA6;&#x4F4E;</li>
<li>&#x5F00;&#x53D1;&#x4EE3;&#x7801;&#x91CF;&#x5C11;</li>
<li>&#x6E32;&#x67D3;&#x6027;&#x80FD;&#x597D;</li>
</ul>
<h2 id="t23. &#x6838;&#x5FC3;&#x601D;&#x60F3;">3. &#x6838;&#x5FC3;&#x601D;&#x60F3; <a href="#t23. &#x6838;&#x5FC3;&#x601D;&#x60F3;"> # </a></h2>
<p>&#x72B6;&#x6001;&#x53D8;&#x5316;&#x5F15;&#x8D77;&#x7684;&#x526F;&#x4F5C;&#x7528;&#x5E94;&#x8BE5;&#x88AB;&#x81EA;&#x52A8;&#x89E6;&#x53D1;</p>
<ul>
<li>&#x5E94;&#x7528;&#x903B;&#x8F91;&#x53EA;&#x9700;&#x8981;&#x4FEE;&#x6539;&#x72B6;&#x6001;&#x6570;&#x636E;&#x5373;&#x53EF;,mobx&#x56DE;&#x81EA;&#x52A8;&#x6E32;&#x67D3;UI&#xFF0C;&#x65E0;&#x9700;&#x4EBA;&#x5DE5;&#x5E72;&#x9884;</li>
<li>&#x6570;&#x636E;&#x53D8;&#x5316;&#x53EA;&#x4F1A;&#x6E32;&#x67D3;&#x5BF9;&#x5E94;&#x7684;&#x7EC4;&#x4EF6;</li>
<li>MobX&#x63D0;&#x4F9B;&#x673A;&#x5236;&#x6765;&#x5B58;&#x50A8;&#x548C;&#x66F4;&#x65B0;&#x5E94;&#x7528;&#x72B6;&#x6001;&#x4F9B; React &#x4F7F;&#x7528;</li>
<li>eact &#x901A;&#x8FC7;&#x63D0;&#x4F9B;&#x673A;&#x5236;&#x628A;&#x5E94;&#x7528;&#x72B6;&#x6001;&#x8F6C;&#x6362;&#x4E3A;&#x53EF;&#x6E32;&#x67D3;&#x7EC4;&#x4EF6;&#x6811;&#x5E76;&#x5BF9;&#x5176;&#x8FDB;&#x884C;&#x6E32;&#x67D3;</li>
</ul>
<p><img src="https://cn.mobx.js.org/flow.png" alt="flow"></p>
<h2 id="t34. &#x73AF;&#x5883;&#x51C6;&#x5907;">4. &#x73AF;&#x5883;&#x51C6;&#x5907; <a href="#t34. &#x73AF;&#x5883;&#x51C6;&#x5907;"> # </a></h2>
<h3 id="t44.1 &#x5B89;&#x88C5;&#x4F9D;&#x8D56;&#x6A21;&#x5757;">4.1 &#x5B89;&#x88C5;&#x4F9D;&#x8D56;&#x6A21;&#x5757; <a href="#t44.1 &#x5B89;&#x88C5;&#x4F9D;&#x8D56;&#x6A21;&#x5757;"> # </a></h3>
<pre><code class="lang-js">pm i webpack webpack-cli babel-core babel-loader babel-preset-env babel-preset-react babel-preset-stage<span class="hljs-number">-0</span> babel-plugin-transform-decorators-legacy mobx mobx-react -D
</code></pre>
<h3 id="t54.2 webpack.config.js">4.2 webpack.config.js <a href="#t54.2 webpack.config.js"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> path=<span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;path&apos;</span>);
<span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">mode</span>: <span class="hljs-string">&apos;development&apos;</span>,
    <span class="hljs-attr">entry</span>: path.resolve(__dirname,<span class="hljs-string">&apos;src/index.js&apos;</span>),
    <span class="hljs-attr">output</span>: {
        <span class="hljs-attr">path</span>: path.resolve(__dirname,<span class="hljs-string">&apos;dist&apos;</span>),
        <span class="hljs-attr">filename</span>:<span class="hljs-string">&apos;main.js&apos;</span>
    },
    <span class="hljs-attr">module</span>: {
        <span class="hljs-attr">rules</span>: [
            {
                <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.jsx?$/</span>,
                <span class="hljs-attr">exclude</span>: <span class="hljs-regexp">/node_modules/</span>,
                <span class="hljs-attr">use</span>: {
                    <span class="hljs-attr">loader</span>: <span class="hljs-string">&apos;babel-loader&apos;</span>,
                    <span class="hljs-attr">options</span>: {
                        <span class="hljs-attr">presets</span>: [<span class="hljs-string">&apos;env&apos;</span>,<span class="hljs-string">&apos;react&apos;</span>,<span class="hljs-string">&apos;stage-0&apos;</span>],
                        <span class="hljs-attr">plugins</span>:[<span class="hljs-string">&apos;transform-decorators-legacy&apos;</span>]
                    }
                }
            }
        ]
    },
    <span class="hljs-attr">devtool</span>:<span class="hljs-string">&apos;inline-source-map&apos;</span>
}
</code></pre>
<h3 id="t64.3 package.json">4.3 package.json <a href="#t64.3 package.json"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-string">&quot;scripts&quot;</span>: {
    <span class="hljs-string">&quot;start&quot;</span>: <span class="hljs-string">&quot;webpack -w&quot;</span>
},
</code></pre>
<h2 id="t75. Decorator">5. Decorator <a href="#t75. Decorator"> # </a></h2>
<h3 id="t85.1 &#x7C7B;&#x7684;&#x4FEE;&#x9970;">5.1 &#x7C7B;&#x7684;&#x4FEE;&#x9970; <a href="#t85.1 &#x7C7B;&#x7684;&#x4FEE;&#x9970;"> # </a></h3>
<ul>
<li>&#x4FEE;&#x9970;&#x5668;&#xFF08;Decorator&#xFF09;&#x51FD;&#x6570;&#xFF0C;&#x7528;&#x6765;&#x4FEE;&#x6539;&#x7C7B;&#x7684;&#x884C;&#x4E3A;</li>
<li>&#x4FEE;&#x9970;&#x5668;&#x662F;&#x4E00;&#x4E2A;&#x5BF9;&#x7C7B;&#x8FDB;&#x884C;&#x5904;&#x7406;&#x7684;&#x51FD;&#x6570;&#x3002;&#x4FEE;&#x9970;&#x5668;&#x51FD;&#x6570;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x5C31;&#x662F;&#x6240;&#x8981;&#x4FEE;&#x9970;&#x7684;&#x76EE;&#x6807;&#x7C7B;</li>
<li>&#x4FEE;&#x9970;&#x5668;&#x672C;&#x8D28;&#x5C31;&#x662F;&#x7F16;&#x8BD1;&#x65F6;&#x6267;&#x884C;&#x7684;&#x51FD;&#x6570;</li>
<li>&#x5982;&#x679C;&#x60F3;&#x6DFB;&#x52A0;&#x5B9E;&#x4F8B;&#x5C5E;&#x6027;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x76EE;&#x6807;&#x7C7B;&#x7684;prototype&#x5BF9;&#x8C61;&#x64CD;&#x4F5C;</li>
</ul>
<pre><code class="lang-js">@testable
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span></span>{

}
<span class="hljs-comment">//&#x4FEE;&#x6539;&#x4E86;Person&#x7684;&#x7C7B;&#x7684;&#x884C;&#x4E3A;&#xFF0C;&#x589E;&#x52A0;&#x4E86;&#x9759;&#x6001;&#x5C5E;&#x6027;isTestable</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testable</span>(<span class="hljs-params">target</span>) </span>{
    target.isTestable=<span class="hljs-literal">true</span>;
}
<span class="hljs-built_in">console</span>.log(Person.isTestable)

@decorator
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span></span>{}
---------------
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span></span>{}
A = decorator(A);
</code></pre>
<h3 id="t95.2 &#x4FEE;&#x9970;&#x5C5E;&#x6027;">5.2 &#x4FEE;&#x9970;&#x5C5E;&#x6027; <a href="#t95.2 &#x4FEE;&#x9970;&#x5C5E;&#x6027;"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Circle</span></span>{
    @readonly PI=<span class="hljs-number">3.14</span>;
}

<span class="hljs-comment">//descriptor {value:func,enumerable:false,configurable:true,writable:true}</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readonly</span>(<span class="hljs-params">target,name,descriptor</span>) </span>{
    <span class="hljs-built_in">console</span>.log(descriptor);
    descriptor.writable=<span class="hljs-literal">false</span>;
}
<span class="hljs-keyword">let</span> c1=<span class="hljs-keyword">new</span> Circle();
c1.PI=<span class="hljs-number">3.15</span>;
<span class="hljs-built_in">console</span>.log(c1.PI);
</code></pre>
<h3 id="t105.3 &#x4FEE;&#x9970;&#x65B9;&#x6CD5;">5.3 &#x4FEE;&#x9970;&#x65B9;&#x6CD5; <a href="#t105.3 &#x4FEE;&#x9970;&#x65B9;&#x6CD5;"> # </a></h3>
<ul>
<li>&#x4FEE;&#x9970;&#x5668;&#x4E0D;&#x4EC5;&#x53EF;&#x4EE5;&#x4FEE;&#x9970;&#x7C7B;&#xFF0C;&#x8FD8;&#x53EF;&#x4EE5;&#x4FEE;&#x9970;&#x7C7B;&#x7684;&#x5C5E;&#x6027;&#x3002;</li>
</ul>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Calculator</span></span>{
    <span class="hljs-comment">//@logger</span>
    add(a,b) {
        <span class="hljs-keyword">return</span> a+b; 
    }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logger</span>(<span class="hljs-params">target,name,descriptor</span>) </span>{
    <span class="hljs-keyword">let</span> oldValue=descriptor.value;
    descriptor.value=<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${name}</span>(<span class="hljs-subst">${<span class="hljs-built_in">Array</span>.prototype.join.call(<span class="hljs-built_in">arguments</span>,<span class="hljs-string">&apos;,&apos;</span>)}</span>)`</span>);
        <span class="hljs-keyword">return</span> oldValue.apply(<span class="hljs-keyword">this</span>,<span class="hljs-built_in">arguments</span>);
    }
}
<span class="hljs-keyword">let</span> oldDescriptor=<span class="hljs-built_in">Object</span>.getOwnPropertyDescriptor(Calculator.prototype,<span class="hljs-string">&apos;add&apos;</span>);
logger(Calculator.prototype,<span class="hljs-string">&apos;add&apos;</span>,oldDescriptor);
<span class="hljs-built_in">Object</span>.defineProperty(Calculator.prototype,<span class="hljs-string">&apos;add&apos;</span>,oldDescriptor);

<span class="hljs-keyword">let</span> calculator=<span class="hljs-keyword">new</span> Calculator();
<span class="hljs-keyword">let</span> ret = calculator.add(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>);
<span class="hljs-built_in">console</span>.log(ret);
</code></pre>
<h2 id="t116. Proxy">6. Proxy <a href="#t116. Proxy"> # </a></h2>
<ul>
<li>Proxy &#x53EF;&#x4EE5;&#x7406;&#x89E3;&#x6210;&#xFF0C;&#x5728;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x4E4B;&#x524D;&#x67B6;&#x8BBE;&#x4E00;&#x5C42;&#x201C;&#x62E6;&#x622A;&#x201D;&#xFF0C;&#x5916;&#x754C;&#x5BF9;&#x8BE5;&#x5BF9;&#x8C61;&#x7684;&#x8BBF;&#x95EE;&#xFF0C;&#x90FD;&#x5FC5;&#x987B;&#x5148;&#x901A;&#x8FC7;&#x8FD9;&#x5C42;&#x62E6;&#x622A;&#xFF0C;&#x56E0;&#x6B64;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x79CD;&#x673A;&#x5236;&#xFF0C;&#x53EF;&#x4EE5;&#x5BF9;&#x5916;&#x754C;&#x7684;&#x8BBF;&#x95EE;&#x8FDB;&#x884C;&#x8FC7;&#x6EE4;&#x548C;&#x6539;&#x5199;</li>
<li>get&#x65B9;&#x6CD5;&#x7528;&#x4E8E;&#x62E6;&#x622A;&#x67D0;&#x4E2A;&#x5C5E;&#x6027;&#x7684;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#xFF0C;&#x53EF;&#x4EE5;&#x63A5;&#x53D7;&#x4E09;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x4F9D;&#x6B21;&#x4E3A;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x3001;&#x5C5E;&#x6027;&#x540D;&#x548C; proxy &#x5B9E;&#x4F8B;&#x672C;&#x8EAB;</li>
<li>set&#x65B9;&#x6CD5;&#x7528;&#x6765;&#x62E6;&#x622A;&#x67D0;&#x4E2A;&#x5C5E;&#x6027;&#x7684;&#x8D4B;&#x503C;&#x64CD;&#x4F5C;&#xFF0C;&#x53EF;&#x4EE5;&#x63A5;&#x53D7;&#x56DB;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x4F9D;&#x6B21;&#x4E3A;&#x76EE;&#x6807;&#x5BF9;&#x8C61;&#x3001;&#x5C5E;&#x6027;&#x540D;&#x3001;&#x5C5E;&#x6027;&#x503C;&#x548C; Proxy &#x5B9E;&#x4F8B;&#x672C;&#x8EAB;</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> proxy = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(target, handler);
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> p1=<span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>({<span class="hljs-attr">name</span>:<span class="hljs-string">&apos;zfpx&apos;</span>},{
    <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">target,key,receiver</span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`getting <span class="hljs-subst">${key}</span>`</span>);
        <span class="hljs-built_in">console</span>.log(receiver);
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">Reflect</span>.get(target,key,receiver);
    },
    <span class="hljs-attr">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">target,key,value,receiver</span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`setting <span class="hljs-subst">${key}</span>`</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">Reflect</span>.set(target,key,value,receiver);
    }
});
<span class="hljs-built_in">console</span>.log(p1.name);
</code></pre>
<h2 id="t127. mobx">7. mobx <a href="#t127. mobx"> # </a></h2>
<h3 id="t137.1 observable">7.1 observable <a href="#t137.1 observable"> # </a></h3>
<ul>
<li>MobX&#x4E3A;&#x73B0;&#x6709;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;(&#x5982;&#x5BF9;&#x8C61;&#xFF0C;&#x6570;&#x7EC4;&#x548C;&#x7C7B;&#x5B9E;&#x4F8B;)&#x6DFB;&#x52A0;&#x4E86;&#x53EF;&#x89C2;&#x5BDF;&#x7684;&#x529F;&#x80FD;&#x3002;</li>
<li><code>observable</code>&#x5C31;&#x662F;&#x4E00;&#x79CD;&#x8BA9;&#x6570;&#x636E;&#x7684;&#x53D8;&#x5316;&#x53EF;&#x4EE5;&#x88AB;&#x89C2;&#x5BDF;&#x7684;&#x65B9;&#x6CD5;</li>
<li>&#x5148;&#x628A;&#x6570;&#x636E;&#x8F6C;&#x5316;&#x6210;&#x53EF;&#x4EE5;&#x88AB;&#x89C2;&#x5BDF;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x90A3;&#x4E48;&#x5BF9;&#x8FD9;&#x4E9B;&#x6570;&#x636E;&#x7684;&#x4FEE;&#x6539;&#x5C31;&#x53EF;&#x4EE5;&#x5907;&#x76D1;&#x89C6;</li>
</ul>
<h4 id="t147.1.1 &#x5F15;&#x7528;&#x7C7B;&#x578B; (observable)">7.1.1 &#x5F15;&#x7528;&#x7C7B;&#x578B; (observable) <a href="#t147.1.1 &#x5F15;&#x7528;&#x7C7B;&#x578B; (observable)"> # </a></h4>
<table>
<thead>
<tr>
<th style="text-align:left">&#x7C7B;&#x578B;</th>
<th style="text-align:left">&#x63CF;&#x8FF0;</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">&#x5BF9;&#x8C61;</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">&#x6570;&#x7EC4;</td>
</tr>
</tbody>
</table>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {observable,isArrayLike}=<span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;mobx&apos;</span>);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">observable2</span>(<span class="hljs-params">target</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(target,{});
}
<span class="hljs-keyword">const</span> p1=observable2({<span class="hljs-attr">name</span>:<span class="hljs-string">&apos;zfpx&apos;</span>});
<span class="hljs-built_in">console</span>.log(p1.name);
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {observable}=<span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;mobx&apos;</span>);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">observable2</span>(<span class="hljs-params">target</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Proxy</span>(target,{

    });
}
<span class="hljs-keyword">const</span> p1=observable([<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>]);
p1.push(<span class="hljs-number">4</span>);
p1.pop();
<span class="hljs-built_in">console</span>.log(p1);
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Array</span>.isArray(p1));
</code></pre>
<h4 id="t157.1.2 &#x57FA;&#x672C;&#x7C7B;&#x578B;(observable.box)">7.1.2 &#x57FA;&#x672C;&#x7C7B;&#x578B;(observable.box) <a href="#t157.1.2 &#x57FA;&#x672C;&#x7C7B;&#x578B;(observable.box)"> # </a></h4>
<table>
<thead>
<tr>
<th style="text-align:left">&#x7C7B;&#x578B;</th>
<th style="text-align:left">&#x63CF;&#x8FF0;</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">String</td>
<td style="text-align:left">&#x5B57;&#x7B26;&#x4E32;</td>
</tr>
<tr>
<td style="text-align:left">Boolean</td>
<td style="text-align:left">&#x5E03;&#x5C14;&#x503C;</td>
</tr>
<tr>
<td style="text-align:left">Number</td>
<td style="text-align:left">&#x6570;&#x5B57;</td>
</tr>
<tr>
<td style="text-align:left">Symbol</td>
<td style="text-align:left">&#x72EC;&#x4E00;&#x65E0;&#x4E8C;&#x7684;&#x503C;</td>
</tr>
</tbody>
</table>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {observable}=<span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;mobx&apos;</span>);
<span class="hljs-keyword">let</span> num=observable.box(<span class="hljs-number">10</span>);
<span class="hljs-keyword">let</span> str=observable.box(<span class="hljs-string">&apos;hello&apos;</span>);
<span class="hljs-keyword">let</span> bool=observable.box(<span class="hljs-literal">true</span>);
<span class="hljs-built_in">console</span>.log(num.get(),str.get(),bool.get());
num.set(<span class="hljs-number">100</span>);
str.set(<span class="hljs-string">&apos;world&apos;</span>);
bool.set(<span class="hljs-literal">false</span>);
<span class="hljs-built_in">console</span>.log(num.get(),str.get(),bool.get());
</code></pre>
<h4 id="t167.1.3 decorator">7.1.3 decorator <a href="#t167.1.3 decorator"> # </a></h4>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {observable} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx&apos;</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    @observable name=<span class="hljs-string">&apos;zfpx&apos;</span>;
    @observable age=<span class="hljs-number">9</span>;
    @observable isMarried=<span class="hljs-literal">false</span>;

    @observable hobbies=[];
    @observable home={<span class="hljs-attr">name</span>:<span class="hljs-string">&apos;&#x5317;&#x4EAC;&apos;</span>};
    @observable skills=<span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();
}
</code></pre>
<h2 id="t178. &#x4F7F;&#x7528;&#x5BF9;&#x53EF;&#x89C2;&#x5BDF;&#x5BF9;&#x8C61;&#x505A;&#x51FA;&#x54CD;&#x5E94;">8. &#x4F7F;&#x7528;&#x5BF9;&#x53EF;&#x89C2;&#x5BDF;&#x5BF9;&#x8C61;&#x505A;&#x51FA;&#x54CD;&#x5E94; <a href="#t178. &#x4F7F;&#x7528;&#x5BF9;&#x53EF;&#x89C2;&#x5BDF;&#x5BF9;&#x8C61;&#x505A;&#x51FA;&#x54CD;&#x5E94;"> # </a></h2>
<h3 id="t188.1 computed">8.1 computed <a href="#t188.1 computed"> # </a></h3>
<ul>
<li>&#x8BA1;&#x7B97;&#x503C;(computed values)&#x662F;&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x73B0;&#x6709;&#x7684;&#x72B6;&#x6001;&#x6216;&#x5176;&#x5B83;&#x8BA1;&#x7B97;&#x503C;&#x884D;&#x751F;&#x51FA;&#x7684;&#x503C;</li>
<li>&#x7EC4;&#x5408;&#x5DF2;&#x6709;&#x7684;&#x53EF;&#x89C2;&#x5BDF;&#x6570;&#x636E;&#xFF0C;&#x6210;&#x4E3A;&#x65B0;&#x7684;&#x53EF;&#x89C2;&#x5BDF;&#x6570;&#x636E;</li>
<li>&#x65E2;&#x662F;&#x53CD;&#x5E94;&#x53C8;&#x662F;&#x53EF;&#x89C2;&#x5BDF;&#x6570;&#x636E;</li>
<li>&#x53EF;&#x4EE5;&#x4F5C;&#x4E3A;&#x51FD;&#x6570;&#x4F7F;&#x7528;&#x4E5F;&#x53EF;&#x4EE5;&#x4F5C;&#x4E3A;decorator&#x4F7F;&#x7528;</li>
<li>&#x4F7F;&#x7528; .get() &#x6765;&#x83B7;&#x53D6;&#x8BA1;&#x7B97;&#x7684;&#x5F53;&#x524D;&#x503C;</li>
<li>&#x4F7F;&#x7528; .observe(callback) &#x6765;&#x89C2;&#x5BDF;&#x503C;&#x7684;&#x6539;&#x53D8;&#x3002;</li>
<li>computed&#x503C;&#x53EF;&#x4EE5;&#x5F15;&#x7528;&#x5176;&#x5B83;computed&#x7684;&#x503C;&#xFF0C;&#x4F46;&#x662F;&#x4E0D;&#x80FD;&#x5FAA;&#x73AF;&#x5F15;&#x7528;</li>
</ul>
<pre><code class="lang-js">
<span class="hljs-keyword">let</span> {observable,computed} = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;mobx&apos;</span>);
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    @observable name=<span class="hljs-string">&apos;zfpx&apos;</span>;
    @observable age=<span class="hljs-number">9</span>;
    @observable area=<span class="hljs-string">&apos;010&apos;</span>;
    @observable number=<span class="hljs-string">&quot;18910092296&quot;</span>

    @observable province=<span class="hljs-string">&quot;&#x5E7F;&#x4E1C;&quot;</span>;
    @observable city=<span class="hljs-string">&quot;&#x4E1C;&#x839E;&quot;</span>;
    @computed get home() {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.province+<span class="hljs-keyword">this</span>.city;
    }
}

<span class="hljs-keyword">let</span> store=<span class="hljs-keyword">new</span> Store();
<span class="hljs-keyword">let</span> cell = computed(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> store.area+<span class="hljs-string">&apos;-&apos;</span>+store.number;
});
cell.observe(<span class="hljs-function"><span class="hljs-params">change</span>=&gt;</span><span class="hljs-built_in">console</span>.log(change));
<span class="hljs-built_in">console</span>.log(cell.get());
store.area=<span class="hljs-string">&apos;020&apos;</span>;
store.number=<span class="hljs-string">&apos;15718856132&apos;</span>;
<span class="hljs-built_in">console</span>.log(cell.get());
<span class="hljs-built_in">console</span>.log(store.home);
store.province=<span class="hljs-string">&apos;&#x5C71;&#x4E1C;&apos;</span>;
store.city=<span class="hljs-string">&apos;&#x6D4E;&#x5357;&apos;</span>;
<span class="hljs-built_in">console</span>.log(store.home);
</code></pre>
<h3 id="t198.2 autorun">8.2 autorun <a href="#t198.2 autorun"> # </a></h3>
<ul>
<li>&#x5982;&#x679C;&#x4F7F;&#x7528;&#x4FEE;&#x9970;&#x5668;&#x6A21;&#x5F0F;&#xFF0C;&#x5219;&#x4E0D;&#x80FD;&#x518D;&#x7528;observe&#x65B9;&#x6CD5;&#x4E86;</li>
<li>&#x5F53;&#x4F60;&#x60F3;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x54CD;&#x5E94;&#x5F0F;&#x51FD;&#x6570;&#xFF0C;&#x800C;&#x8BE5;&#x51FD;&#x6570;&#x672C;&#x8EAB;&#x6C38;&#x8FDC;&#x4E0D;&#x4F1A;&#x6709;&#x89C2;&#x5BDF;&#x8005;&#x65F6;,&#x53EF;&#x4EE5;&#x4F7F;&#x7528; mobx.autorun</li>
<li>&#x5F53;&#x4F7F;&#x7528; autorun &#x65F6;&#xFF0C;&#x6240;&#x63D0;&#x4F9B;&#x7684;&#x51FD;&#x6570;&#x603B;&#x662F;&#x7ACB;&#x5373;&#x88AB;&#x89E6;&#x53D1;&#x4E00;&#x6B21;&#xFF0C;&#x7136;&#x540E;&#x6BCF;&#x6B21;&#x5B83;&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x6539;&#x53D8;&#x65F6;&#x4F1A;&#x518D;&#x6B21;&#x88AB;&#x89E6;&#x53D1;</li>
<li>&#x6570;&#x636E;&#x6E32;&#x67D3;&#x540E;&#x81EA;&#x52A8;&#x6E32;&#x67D3;</li>
</ul>
<pre><code class="lang-js">autorun(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    <span class="hljs-comment">//console.log(store.province,store.city);</span>
    <span class="hljs-built_in">console</span>.log(store.home);
});

store.province=<span class="hljs-string">&apos;&#x5C71;&#x4E1C;&apos;</span>;
store.city=<span class="hljs-string">&apos;&#x6D4E;&#x5357;&apos;</span>;
</code></pre>
<h3 id="t208.3 when">8.3 when <a href="#t208.3 when"> # </a></h3>
<ul>
<li>when &#x89C2;&#x5BDF;&#x5E76;&#x8FD0;&#x884C;&#x7ED9;&#x5B9A;&#x7684; <code>predicate</code>&#xFF0C;&#x76F4;&#x5230;&#x8FD4;&#x56DE;true&#x3002; </li>
<li>&#x4E00;&#x65E6;&#x8FD4;&#x56DE; true&#xFF0C;&#x7ED9;&#x5B9A;&#x7684; effect &#x5C31;&#x4F1A;&#x88AB;&#x6267;&#x884C;&#xFF0C;&#x7136;&#x540E; autorunner(&#x81EA;&#x52A8;&#x8FD0;&#x884C;&#x7A0B;&#x5E8F;) &#x4F1A;&#x88AB;&#x6E05;&#x7406;&#x3002; </li>
<li>&#x8BE5;&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x6E05;&#x7406;&#x5668;&#x4EE5;&#x63D0;&#x524D;&#x53D6;&#x6D88;&#x81EA;&#x52A8;&#x8FD0;&#x884C;&#x7A0B;&#x5E8F;&#x3002;</li>
</ul>
<pre><code class="lang-js">when(predicate: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> boolean, effect?: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">void</span>, options?)
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> dispose = when(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> store.age&gt;=<span class="hljs-number">18</span>,()=&gt;{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;&#x4F60;&#x5DF2;&#x7ECF;&#x6210;&#x5E74;&#x4E86;!&apos;</span>)
});
dispose();
store.age=<span class="hljs-number">10</span>;
store.age=<span class="hljs-number">20</span>;
store.age=<span class="hljs-number">30</span>;
</code></pre>
<h3 id="t218.4 reaction">8.4 reaction <a href="#t218.4 reaction"> # </a></h3>
<ul>
<li><code>autorun</code>&#x7684;&#x53D8;&#x79CD;&#xFF0C;<code>autorun</code>&#x4F1A;&#x81EA;&#x52A8;&#x89E6;&#x53D1;&#xFF0C;<code>reaction</code>&#x5BF9;&#x4E8E;&#x5982;&#x4F55;&#x8FFD;&#x8E2A;<code>observable</code>&#x8D4B;&#x4E88;&#x4E86;&#x66F4;&#x7EC6;&#x7C92;&#x5EA6;&#x7684;&#x63A7;&#x5236;</li>
<li>&#x5B83;&#x63A5;&#x6536;&#x4E24;&#x4E2A;&#x51FD;&#x6570;&#x53C2;&#x6570;&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;(&#x6570;&#x636E; &#x51FD;&#x6570;)&#x662F;&#x7528;&#x6765;&#x8FFD;&#x8E2A;&#x5E76;&#x8FD4;&#x56DE;&#x6570;&#x636E;&#x4F5C;&#x4E3A;&#x7B2C;&#x4E8C;&#x4E2A;&#x51FD;&#x6570;(&#x6548;&#x679C; &#x51FD;&#x6570;)&#x7684;&#x8F93;&#x5165;</li>
<li>&#x4E0D;&#x540C;&#x4E8E;<code>autorun</code>&#x7684;&#x662F;&#x5F53;&#x521B;&#x5EFA;&#x65F6;&#x6548;&#x679C; &#x51FD;&#x6570;&#x4E0D;&#x4F1A;&#x76F4;&#x63A5;&#x8FD0;&#x884C;&#xFF0C;&#x53EA;&#x6709;&#x5728;&#x6570;&#x636E;&#x8868;&#x8FBE;&#x5F0F;&#x9996;&#x6B21;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x65B0;&#x503C;&#x540E;&#x624D;&#x4F1A;&#x8FD0;&#x884C;</li>
<li>&#x53EF;&#x4EE5;&#x7528;&#x5728;&#x767B;&#x5F55;&#x4FE1;&#x606F;&#x5B58;&#x50A8;&#x548C;&#x5199;&#x7F13;&#x5B58;&#x903B;&#x8F91;</li>
</ul>
<pre><code class="lang-js">reaction(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> [store.province,store.city],arr =&gt; <span class="hljs-built_in">console</span>.log(arr.join(<span class="hljs-string">&apos;,&apos;</span>)));
store.province=<span class="hljs-string">&apos;&#x5C71;&#x4E1C;&apos;</span>;
store.city=<span class="hljs-string">&apos;&#x6D4E;&#x5357;&apos;</span>;
</code></pre>
<h2 id="t229. action">9. action <a href="#t229. action"> # </a></h2>
<ul>
<li>&#x524D;&#x9762;&#x7684;&#x65B9;&#x5F0F;&#x6BCF;&#x6B21;&#x4FEE;&#x6539;&#x90FD;&#x4F1A;&#x89E6;&#x53D1;<code>autorun</code>&#x548C;<code>reaction</code>&#x6267;&#x884C;</li>
<li>&#x7528;&#x6237;&#x4E00;&#x6B21;&#x64CD;&#x4F5C;&#x9700;&#x8981;&#x4FEE;&#x6539;&#x591A;&#x4E2A;&#x53D8;&#x91CF;&#xFF0C;&#x4F46;&#x662F;&#x89C6;&#x56FE;&#x66F4;&#x65B0;&#x53EA;&#x9700;&#x8981;&#x4E00;&#x6B21;</li>
<li>&#x4EFB;&#x4F55;&#x5E94;&#x7528;&#x90FD;&#x6709;&#x52A8;&#x4F5C;,&#x52A8;&#x4F5C;&#x662F;&#x4EFB;&#x4F55;&#x7528;&#x6765;&#x4FEE;&#x6539;&#x72B6;&#x6001;&#x7684;&#x4E1C;&#x897F;</li>
<li>&#x52A8;&#x4F5C;&#x4F1A;&#x5206;&#x6279;&#x5904;&#x7406;&#x53D8;&#x5316;&#x5E76;&#x53EA;&#x5728;(&#x6700;&#x5916;&#x5C42;&#x7684;)&#x52A8;&#x4F5C;&#x5B8C;&#x6210;&#x540E;&#x901A;&#x77E5;&#x8BA1;&#x7B97;&#x503C;&#x548C;&#x53CD;&#x5E94;</li>
<li>&#x8FD9;&#x5C06;&#x786E;&#x4FDD;&#x5728;&#x52A8;&#x4F5C;&#x5B8C;&#x6210;&#x4E4B;&#x524D;&#xFF0C;&#x5728;&#x52A8;&#x4F5C;&#x671F;&#x95F4;&#x751F;&#x6210;&#x7684;&#x4E2D;&#x95F4;&#x503C;&#x6216;&#x672A;&#x5B8C;&#x6210;&#x7684;&#x503C;&#x5BF9;&#x5E94;&#x7528;&#x7684;&#x5176;&#x4F59;&#x90E8;&#x5206;&#x662F;&#x4E0D;&#x53EF;&#x89C1;&#x7684;<h3 id="t239.1 action">9.1 action <a href="#t239.1 action"> # </a></h3>
</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> {observable,computed,autorun,when,reaction,action} = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;mobx&apos;</span>);
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    @observable province=<span class="hljs-string">&quot;&#x5E7F;&#x4E1C;&quot;</span>;
    @observable city=<span class="hljs-string">&quot;&#x4E1C;&#x839E;&quot;</span>;
    @action moveHome(province,city) {
         <span class="hljs-keyword">this</span>.province=province;
         <span class="hljs-keyword">this</span>.city=city;
    }
}
<span class="hljs-keyword">let</span> store=<span class="hljs-keyword">new</span> Store();
reaction(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> [store.province,store.city],arr =&gt; <span class="hljs-built_in">console</span>.log(arr.join(<span class="hljs-string">&apos;,&apos;</span>)));
store.moveHome(<span class="hljs-string">&apos;&#x5C71;&#x4E1C;&apos;</span>,<span class="hljs-string">&apos;&#x6D4E;&#x5357;&apos;</span>);
</code></pre>
<h3 id="t249.2 action.bound">9.2 action.bound <a href="#t249.2 action.bound"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> {observable,computed,autorun,when,reaction,action} = <span class="hljs-built_in">require</span>(<span class="hljs-string">&apos;mobx&apos;</span>);
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    @observable province=<span class="hljs-string">&quot;&#x5E7F;&#x4E1C;&quot;</span>;
    @observable city=<span class="hljs-string">&quot;&#x4E1C;&#x839E;&quot;</span>;
    @action.bound moveHome(province,city) {
         <span class="hljs-keyword">this</span>.province=province;
         <span class="hljs-keyword">this</span>.city=city;
    }
}
<span class="hljs-keyword">let</span> store=<span class="hljs-keyword">new</span> Store();
reaction(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> [store.province,store.city],arr =&gt; <span class="hljs-built_in">console</span>.log(arr.join(<span class="hljs-string">&apos;,&apos;</span>)));
<span class="hljs-keyword">let</span> moveHome=store.moveHome;
moveHome(<span class="hljs-string">&apos;&#x5C71;&#x4E1C;&apos;</span>,<span class="hljs-string">&apos;&#x6D4E;&#x5357;&apos;</span>);
</code></pre>
<h3 id="t259.3 runInAction">9.3 runInAction <a href="#t259.3 runInAction"> # </a></h3>
<pre><code class="lang-js">runInAction(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
    store.province=<span class="hljs-string">&apos;&#x5C71;&#x4E1C;&apos;</span>;
    store.city=<span class="hljs-string">&apos;&#x6D4E;&#x5357;&apos;</span>;
});
</code></pre>
<h2 id="t2610. mobx&#x5E94;&#x7528;">10. mobx&#x5E94;&#x7528; <a href="#t2610. mobx&#x5E94;&#x7528;"> # </a></h2>
<ul>
<li>mobx-react &#x6838;&#x5FC3;&#x662F;&#x5C06;render&#x65B9;&#x6CD5;&#x5305;&#x88C5;&#x4E3A;autorun</li>
<li>&#x8C01;&#x7528;&#x5230;&#x4E86;&#x53EF;&#x89C2;&#x5BDF;&#x5C5E;&#x6027;&#xFF0C;&#x5C31;&#x9700;&#x8981;&#x88AB;observer&#x4FEE;&#x9970;&#xFF0C;&#x6309;&#x9700;&#x6E32;&#x67D3;<pre><code class="lang-js">cnpm i react react-dom mobx-react -S
</code></pre>
</li>
</ul>
<h3 id="t2710.1 &#x8BA1;&#x6570;&#x5668;">10.1 &#x8BA1;&#x6570;&#x5668; <a href="#t2710.1 &#x8BA1;&#x6570;&#x5668;"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-dom&apos;</span>;
<span class="hljs-keyword">import</span> {observable,action} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx&apos;</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;prop-types&apos;</span>;
<span class="hljs-keyword">import</span> {observer} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx-react&apos;</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    @observable number=<span class="hljs-number">0</span>;
    @action.bound add() {
        <span class="hljs-keyword">this</span>.number++;
    }
}
<span class="hljs-keyword">let</span> store=<span class="hljs-keyword">new</span> Store();

@observer
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{store.number}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{store.add}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        )
    }
}
ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Counter</span>/&gt;</span></span>,<span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">&apos;#root&apos;</span>));
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-dom&apos;</span>;
<span class="hljs-keyword">import</span> {observable,action} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx&apos;</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;prop-types&apos;</span>;
<span class="hljs-keyword">import</span> {observer} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx-react&apos;</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    @observable counter={<span class="hljs-attr">number</span>:<span class="hljs-number">0</span>};
    @action.bound add() {
        <span class="hljs-keyword">this</span>.counter.number++;
    }
}
<span class="hljs-keyword">let</span> store=<span class="hljs-keyword">new</span> Store();
@observer
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{this.props.counter.number}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.props.add}</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        )
    }
}
ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Counter</span>
    <span class="hljs-attr">counter</span>=<span class="hljs-string">{store.counter}</span>
    <span class="hljs-attr">add</span>=<span class="hljs-string">{store.add}</span>
/&gt;</span>,document.querySelector(&apos;#root&apos;));
</span></code></pre>
<h3 id="t2810.2 TODO">10.2 TODO <a href="#t2810.2 TODO"> # </a></h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component,Fragment} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-dom&apos;</span>;
<span class="hljs-keyword">import</span> {observable,action, computed} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx&apos;</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;prop-types&apos;</span>;
<span class="hljs-keyword">import</span> {observer,PropTypes <span class="hljs-keyword">as</span> ObservablePropTypes} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx-react&apos;</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Todo</span></span>{
    id=<span class="hljs-built_in">Math</span>.random();
    @observable text=<span class="hljs-string">&apos;&apos;</span>;
    @observable completed=<span class="hljs-literal">false</span>;
    <span class="hljs-keyword">constructor</span>(text) {
        <span class="hljs-keyword">this</span>.text=text;
    }
    @action.bound toggle() {
        <span class="hljs-keyword">this</span>.completed=!<span class="hljs-keyword">this</span>.completed;
    }
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span></span>{
    @observable todos=[];
    @computed get left() {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.todos.filter(<span class="hljs-function"><span class="hljs-params">todo</span>=&gt;</span>!todo.completed).length;
    }
    @computed get filterTodos() {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.todos.filter(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> {
            <span class="hljs-keyword">switch</span> (<span class="hljs-keyword">this</span>.filter) {
                <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;completed&apos;</span>:
                    <span class="hljs-keyword">return</span> todo.completed;
                <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;uncompleted&apos;</span>:
                    <span class="hljs-keyword">return</span> !todo.completed;
                <span class="hljs-keyword">default</span>:
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
            }
        });
    }
    @observable filter=<span class="hljs-string">&apos;all&apos;</span>;
    @action.bound changeFilter(filter) {

        <span class="hljs-keyword">this</span>.filter=filter;
        <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.filter);
    }
    @action.bound addTodo(text) {
        <span class="hljs-keyword">this</span>.todos.push(<span class="hljs-keyword">new</span> Todo(text));
    }
    @action.bound removeTodo(todo) {
        <span class="hljs-keyword">this</span>.todos.remove(todo);
    }
}
@observer
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TodoItem</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
    <span class="hljs-keyword">static</span> porpTypes={
        <span class="hljs-attr">todo</span>: PropTypes.shape({
            <span class="hljs-attr">id</span>: PropTypes.number.isRequired,
            <span class="hljs-attr">text</span>: PropTypes.string.isRequired,
            <span class="hljs-attr">completed</span>:PropTypes.bool.isRequired
        }).isRequired
    }
    render() {
        <span class="hljs-keyword">let</span> {todo}=<span class="hljs-keyword">this</span>.props;
        <span class="hljs-keyword">return</span> (
            &lt;Fragment&gt;
                &lt;input
                    type=&quot;checkbox&quot;
                    onChange={todo.toggle}
                    checked={todo.completed} /&gt;
                &lt;span className={todo.completed? &apos;completed&apos;:&apos;&apos;}&gt;{todo.text}&lt;/span&gt;

            &lt;/Fragment&gt;
        )
    }
}
@observer
class TodoList extends Component{
    static propsTypes={
        store: PropTypes.shape({
            addTodo:PropTypes.func,
            todos:ObservablePropTypes.observableArrayOf(ObservablePropTypes.observableObject)
        }).isRequired
    };
    state={text:&apos;&apos;}
    handleSubmit=(event) =&gt; {
        event.preventDefault();
        this.props.store.addTodo(this.state.text);
        this.setState({text:&apos;&apos;});
    }
    handleChange=(event) =&gt; {
        this.setState({text:event.target.value});
    }
    render() {
        let {filterTodos,left,removeTodo,filter,changeFilter}=this.props.store;
        return (
            &lt;div className=&quot;todo-list&quot;&gt;
                &lt;form onSubmit={this.handleSubmit}&gt;
                    &lt;input placeholder=&quot;&#x8BF7;&#x8F93;&#x5165;&#x5F85;&#x529E;&#x4E8B;&#x9879;&quot; type=&quot;text&quot; value={this.state.text} onChange={this.handleChange}/&gt;
                &lt;/form&gt;
                &lt;ul&gt;
                    {
                        filterTodos.map(todo =&gt; (
                            &lt;li key={todo.id}&gt;
                                &lt;TodoItem todo={todo} /&gt;
                                &lt;button onClick={()=&gt;removeTodo(todo)}&gt;X&lt;/button&gt;
                            &lt;/li&gt;
                        ))
                    }
                &lt;/ul&gt;
                &lt;p&gt;
                    &lt;span&gt;&#x4F60;&#x8FD8;&#x6709;{left}&#x4EF6;&#x5F85;&#x529E;&#x4E8B;&#x9879;!&lt;/span&gt;
                    &lt;button
                        onClick={()=&gt;changeFilter(&apos;all&apos;)}
                        className={filter===&apos;all&apos;?&apos;active&apos;:&apos;&apos;}&gt;&#x5168;&#x90E8;&lt;/button&gt;
                    &lt;button onClick={() =&gt; changeFilter(&apos;uncompleted&apos;)}
                        className={filter===&apos;uncompleted&apos;?&apos;active&apos;:&apos;&apos;}&gt;&#x672A;&#x5B8C;&#x6210;&lt;/button&gt;
                    &lt;button
                        onClick={()=&gt;changeFilter(&apos;completed&apos;)}
                        className={filter===&apos;completed&apos;?&apos;active&apos;:&apos;&apos;}&gt;&#x5DF2;&#x5B8C;&#x6210;&lt;/button&gt;
                &lt;/p&gt;
            &lt;/div&gt;
        )
    }
}
let store=new Store();
ReactDOM.render(&lt;TodoList store={store}/&gt;,document.querySelector(&apos;#root&apos;));
</code></pre>
<h2 id="t2911.&#x4F18;&#x5316;">11.&#x4F18;&#x5316; <a href="#t2911.&#x4F18;&#x5316;"> # </a></h2>
<h3 id="t3011.1 observe">11.1 observe <a href="#t3011.1 observe"> # </a></h3>
<pre><code class="lang-js">    <span class="hljs-keyword">constructor</span>() {
        observe(<span class="hljs-keyword">this</span>.todos,change =&gt; {
            <span class="hljs-built_in">console</span>.log(change);
            <span class="hljs-keyword">this</span>.disposers.forEach(<span class="hljs-function"><span class="hljs-params">disposer</span> =&gt;</span> disposer());
            <span class="hljs-keyword">this</span>.disposers=[];
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> todo <span class="hljs-keyword">of</span> change.object) {
                <span class="hljs-keyword">this</span>.disposers.push(observe(todo,change =&gt; {
                    <span class="hljs-keyword">this</span>.save();
                    <span class="hljs-comment">//console.log(change)</span>
                }));
            }
            <span class="hljs-keyword">this</span>.save();
        });
    }
</code></pre>
<h3 id="t3111.2 spy">11.2 spy <a href="#t3111.2 spy"> # </a></h3>
<pre><code class="lang-js">spy(<span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
    <span class="hljs-comment">//console.log(event);</span>
})
</code></pre>
<h3 id="t3211.3 toJS">11.3 toJS <a href="#t3211.3 toJS"> # </a></h3>
<pre><code class="lang-js">    <span class="hljs-keyword">constructor</span>() {
        observe(<span class="hljs-keyword">this</span>.todos,change =&gt; {
            <span class="hljs-built_in">console</span>.log(change);
            <span class="hljs-keyword">this</span>.disposers.forEach(<span class="hljs-function"><span class="hljs-params">disposer</span> =&gt;</span> disposer());
            <span class="hljs-keyword">this</span>.disposers=[];
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> todo <span class="hljs-keyword">of</span> change.object) {
                <span class="hljs-keyword">this</span>.disposers.push(observe(todo,change =&gt; {
                    <span class="hljs-keyword">this</span>.save();
                    <span class="hljs-comment">//console.log(change)</span>
                }));
            }
            <span class="hljs-keyword">this</span>.save();
        });
    }
    save() {
        localStorage.setItem(<span class="hljs-string">&apos;todos&apos;</span>,<span class="hljs-built_in">JSON</span>.stringify(toJS(<span class="hljs-keyword">this</span>.todos)));
    }
</code></pre>
<h3 id="t3311.4 trace">11.4 trace <a href="#t3311.4 trace"> # </a></h3>
<pre><code class="lang-js">trace
</code></pre>
<h3 id="t3412. &#x4F18;&#x5316;">12. &#x4F18;&#x5316; <a href="#t3412. &#x4F18;&#x5316;"> # </a></h3>
<ul>
<li>&#x628A;&#x89C6;&#x56FE;&#x62C6;&#x89E3;&#x7684;&#x66F4;&#x7EC6;&#x81F4;</li>
<li>&#x4F7F;&#x7528;&#x4E13;&#x95E8;&#x7684;&#x89C6;&#x56FE;&#x6E32;&#x67D3;&#x5217;&#x8868;&#x6570;&#x636E;</li>
<li><p>&#x5C3D;&#x53EF;&#x80FD;&#x665A;&#x7684;&#x89E3;&#x6784;&#x4F7F;&#x7528;&#x6570;&#x636E;</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component,Fragment} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-dom&apos;</span>;
<span class="hljs-keyword">import</span> {trace,observable,action, computed, observe, spy,toJS} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx&apos;</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;prop-types&apos;</span>;
<span class="hljs-keyword">import</span> {observer,PropTypes <span class="hljs-keyword">as</span> ObservablePropTypes} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;mobx-react&apos;</span>;
spy(<span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-comment">//console.log(event);</span>
})
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Todo</span></span>{
  id=<span class="hljs-built_in">Math</span>.random();
  @observable text=<span class="hljs-string">&apos;&apos;</span>;
  @observable completed=<span class="hljs-literal">false</span>;
  <span class="hljs-keyword">constructor</span>(text) {
      <span class="hljs-keyword">this</span>.text=text;

  }
  @action.bound toggle() {
      <span class="hljs-keyword">this</span>.completed=!<span class="hljs-keyword">this</span>.completed;
  }
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span></span>{
  disposers=[];
  <span class="hljs-keyword">constructor</span>() {
      observe(<span class="hljs-keyword">this</span>.todos,change =&gt; {
          <span class="hljs-built_in">console</span>.log(change);

          <span class="hljs-keyword">this</span>.disposers.forEach(<span class="hljs-function"><span class="hljs-params">disposer</span> =&gt;</span> disposer());
          <span class="hljs-keyword">this</span>.disposers=[];
          <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> todo <span class="hljs-keyword">of</span> change.object) {
              <span class="hljs-keyword">this</span>.disposers.push(observe(todo,change =&gt; {
                  <span class="hljs-keyword">this</span>.save();
                  <span class="hljs-comment">//console.log(change)</span>
              }));
          }
          <span class="hljs-keyword">this</span>.save();
      });
  }
  save() {
      localStorage.setItem(<span class="hljs-string">&apos;todos&apos;</span>,<span class="hljs-built_in">JSON</span>.stringify(toJS(<span class="hljs-keyword">this</span>.todos)));
  }
  @observable todos=[];
  @computed get left() {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.todos.filter(<span class="hljs-function"><span class="hljs-params">todo</span>=&gt;</span>!todo.completed).length;
  }
  @computed get filterTodos() {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.todos.filter(<span class="hljs-function"><span class="hljs-params">todo</span> =&gt;</span> {
          <span class="hljs-keyword">switch</span> (<span class="hljs-keyword">this</span>.filter) {
              <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;completed&apos;</span>:
                  <span class="hljs-keyword">return</span> todo.completed;
              <span class="hljs-keyword">case</span> <span class="hljs-string">&apos;uncompleted&apos;</span>:
                  <span class="hljs-keyword">return</span> !todo.completed;
              <span class="hljs-keyword">default</span>:
                  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
          }
      });
  }
  @observable filter=<span class="hljs-string">&apos;all&apos;</span>;
  @action.bound changeFilter(filter) {

      <span class="hljs-keyword">this</span>.filter=filter;
      <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.filter);
  }
  @action.bound addTodo(text) {
      <span class="hljs-keyword">this</span>.todos.push(<span class="hljs-keyword">new</span> Todo(text));
  }
  @action.bound removeTodo(todo) {
      <span class="hljs-keyword">this</span>.todos.remove(todo);
  }
}
@observer
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TodoItem</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
  <span class="hljs-keyword">static</span> porpTypes={
      <span class="hljs-attr">todo</span>: PropTypes.shape({
          <span class="hljs-attr">id</span>: PropTypes.number.isRequired,
          <span class="hljs-attr">text</span>: PropTypes.string.isRequired,
          <span class="hljs-attr">completed</span>:PropTypes.bool.isRequired
      }).isRequired
  }
  render() {
      trace();
      <span class="hljs-keyword">let</span> {todo}=<span class="hljs-keyword">this</span>.props;
      <span class="hljs-keyword">return</span> (
          &lt;Fragment&gt;
              &lt;input
                  type=&quot;checkbox&quot;
                  onChange={todo.toggle}
                  checked={todo.completed} /&gt;
              &lt;span className={todo.completed? &apos;completed&apos;:&apos;&apos;}&gt;{todo.text}&lt;/span&gt;

          &lt;/Fragment&gt;
      )
  }
}
@observer
class TodoFooter extends Component{
  static propTypes={

  };
  render() {
      trace();
      let {left,filter} = this.props.store;
      return (
          &lt;div&gt;
                  &lt;span&gt;&#x4F60;&#x8FD8;&#x6709;{left}&#x4EF6;&#x5F85;&#x529E;&#x4E8B;&#x9879;!&lt;/span&gt;
                  &lt;button
                      onClick={()=&gt;changeFilter(&apos;all&apos;)}
                      className={filter===&apos;all&apos;?&apos;active&apos;:&apos;&apos;}&gt;&#x5168;&#x90E8;&lt;/button&gt;
                  &lt;button onClick={() =&gt; changeFilter(&apos;uncompleted&apos;)}
                      className={filter===&apos;uncompleted&apos;?&apos;active&apos;:&apos;&apos;}&gt;&#x672A;&#x5B8C;&#x6210;&lt;/button&gt;
                  &lt;button
                      onClick={()=&gt;changeFilter(&apos;completed&apos;)}
                      className={filter===&apos;completed&apos;?&apos;active&apos;:&apos;&apos;}&gt;&#x5DF2;&#x5B8C;&#x6210;&lt;/button&gt;
              &lt;/div&gt;
      )
  }
}    
@observer
class TodoViews extends Component{
  render() {
      return (
              &lt;ul&gt;
                  {
                      this.props.store.filterTodos.map(todo =&gt; (
                          &lt;li key={todo.id}&gt;
                              &lt;TodoItem todo={todo} /&gt;
                              &lt;button onClick={()=&gt;removeTodo(todo)}&gt;X&lt;/button&gt;
                          &lt;/li&gt;
                      ))
                  }
              &lt;/ul&gt;
      )
  }
}    
@observer
class TodoHeader extends Component{
  state={text:&apos;&apos;}
  handleSubmit=(event) =&gt; {
      event.preventDefault();
      this.props.store.addTodo(this.state.text);
      this.setState({text:&apos;&apos;});
  }
  handleChange=(event) =&gt; {
      this.setState({text:event.target.value});
  }
  render() {
      return (
          &lt;form onSubmit={this.handleSubmit}&gt;
                  &lt;input placeholder=&quot;&#x8BF7;&#x8F93;&#x5165;&#x5F85;&#x529E;&#x4E8B;&#x9879;&quot; type=&quot;text&quot; value={this.state.text} onChange={this.handleChange}/&gt;
              &lt;/form&gt;
      )
  }
}
@observer
class TodoList extends Component{
  static propsTypes={
      store: PropTypes.shape({
          addTodo:PropTypes.func,
          todos:ObservablePropTypes.observableArrayOf(ObservablePropTypes.observableObject)
      }).isRequired
  };

  render() {
      trace();
      return (
          &lt;div className=&quot;todo-list&quot;&gt;
              &lt;TodoHeader store={this.props.store}/&gt;
              &lt;TodoViews store={this.props.store}/&gt;
              &lt;TodoFooter store={this.props.store}/&gt;
          &lt;/div&gt;
      )
  }
}
let store=new Store();
ReactDOM.render(&lt;TodoList store={store}/&gt;,document.querySelector(&apos;#root&apos;));
</code></pre>
</li>
</ul>

        <div class="copyright">Powered by <a href="https://github.com/jaywcjlove/idoc" target="_blank">idoc</a>. Dependence <a href="https://nodejs.org">Node.js</a> run.</div>
    </div>
    
</div>

<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.js"></script>
<script>
$('.warpper .page-toc ul ul li a').on('click',function(){
  $('.warpper .page-toc ul ul li a').removeClass('my-active')
  $(this).addClass('my-active')
})
  // if (!$('.understand-me').length) {
  //   var bar = $(window).height() - $('.navbar ').height() - $('.page-toc').position().top;
  //   var count = bar / 26 / 2;
  //   var barHeight = $('.page-toc').outerHeight();
  //   $('.page-toc li').eq(0).children('a').addClass('red');
  //   var arr = [];
  //   $("h1,h2,h3,h4,h5,h6").each(function () {
  //     arr.push($(this).position().top);
  //   });
  //   var timer
  //   function dark() {
  //     clearTimeout(timer)
  //      timer = setTimeout(function () {
  //      var top = Math.abs($('.page-toc > ul').position().top);
  //      var cur = $('.content').scrollTop();
  //      for (var i = arr.length; i >= 0; i--) {
  //        if (arr[i] <= cur) {
  //          break;
  //        }
  //      }
  //      if (i === -1) {
  //        i = 0;
  //      }
  //      $('.page-toc li a').removeClass('red');
  //      $('.page-toc li').eq(i).children('a').addClass('red');
  //      let height = $('.page-toc li').eq(i).position().top-$('.page-toc').height(); // 如果当前的offset出去了 回到中间可好？
  //      $('.page-toc').scrollTop(height+$('.page-toc').height()/2);
  //    },200)
  //   }

  //   $('.content').on('scroll', dark);
  // }
</script>
<style>

    /* ::-webkit-scrollbar{width:14px;}
    ::-webkit-scrollbar-track{background-color:transparent;}
    ::-webkit-scrollbar-thumb{background-color:transparent;}
    ::-webkit-scrollbar-thumb:hover {background-color:transparent}
    ::-webkit-scrollbar-thumb:active {background-color:transparent} */

    .page-toc > ul .red {
        background: #f3f3f3;
        z-index: 1;
        border-left: 3px solid #009a61;
        -webkit-transition: all .2s ease;
        transition: all .2s ease;
        color: #000
    }





</style>
</body>
</html>
